package uk.org.landeg.euler.problems;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;

import uk.org.landeg.euler.problems.framework.AbstractProblem;

public class Problem026 extends AbstractProblem {
	public static void main(String[] args) {
//		ProblemLauncher launcher = new ProblemLauncher(new Problem026());
//		launcher.solve();
//		System.out.println(recip(439,1500));
//		System.out.println(extractPattern(recip(439,1500)).length);
//		System.exit(0);
		int n = 2;
		int maxLen = 0;
		String out;
		int[] pat = null;
		int max = 0;
		Map<Integer,Integer> cycles = new HashMap<Integer, Integer>();
		ArrayList<Integer> thisRun = new ArrayList<Integer>();
		ArrayList<Integer> nextRun = new ArrayList<Integer>();
		String recip = null;
		for (int test = 1; test< 1000 ; test++) {
			recip = recip(test,5000);
			if (recip.length() > 0) {
				if (recip.length() < 5000) {
					System.out.println("non rec : " + test);
				} else {
					pat = (extractPattern(recip));
//					System.out.println(Arrays.toString(pat));
					if (pat.length > maxLen) {
						maxLen = pat.length;
						max = test;
						System.out.println("New max " + max + " - " + maxLen);
					}
				}
				
			}
		}
		
//		System.out.println(recip);
//		System.out.println(Arrays.toString(extractPattern(recip)));
	}

	@Override
	public Object solve() {
		int maxSeqLen = 0, maxSeqN = 0;
		int sequence[];
		Vector<Integer> thisPass = new Vector<Integer>();
		Vector<Integer> nextPass = new Vector<Integer>();
		int patternLen = 700;
		
		for (int x = 2 ; x<= 1000 ; x++) {
			thisPass.add(x);
		}
		
		System.out.println(extractPattern(recip(7, 4 * patternLen)).length);
//		do {
		nextPass = new Vector<Integer>();
		for (int n : thisPass) {
			sequence = extractPattern(recip(n, 4 * patternLen));
			if (sequence != null) {
				if (sequence.length >= maxSeqLen) {
					maxSeqLen = sequence.length;
					maxSeqN = n;
					nextPass.add(n);
					notes.add(n + "\t" + sequence.length);
				}
			}
		}
		thisPass = nextPass;
//		} while (nextPass.size() > 1);
		System.out.println(nextPass);
		return nextPass.get(nextPass.size() - 1) + "(" + maxSeqLen + ")";
//		return recip(113, 400);
	}

	@Override
	public String getDescription() {
		return "Find the value of d < 1000 for which 1/d contains the longest recurring cycle.";
	}

	@Override
	public Integer getProblemNumber() {
		return 26;
	}

	
	public static int[] extractPattern (String s) {
		int digits[] = new int[s.length()];
		int idx = 0;
		for (char c : s.toCharArray()) {
			digits[idx++] = (int)c - (int)'0';
		}
		return extractPattern(digits);
	}	
	
	/** 
	 * attempt to extract a repeating pattern in the array n
	 * @param n
	 * @return
	 */
	public static int[] extractPattern (int n[]) {
		int scan1, scan2, scan3;
		int comp1, comp2, comp3;
		int scanSize = 0;
		int bounds = n.length / 3;
		int offset = 0;
		int testDigit;
		int[] pattern;
		boolean isCandidate;
		for (offset = 0 ; offset < n.length/4 ; offset++) {
			for (scanSize = 1 ; scanSize <= bounds-1 ; scanSize++) {
				scan1 = offset;
				scan2 = offset + scanSize ;
				scan3 = offset + scanSize * 2;
				if (n[scan1] == n[scan2] && n[scan1] == n[scan3]) {
					// matching digit, check following digits...
					isCandidate = true;
					pattern = new int[scanSize];
					for (testDigit = 0 ; testDigit < scan2-scan1 ; testDigit++) {
						comp1 = scan1 + testDigit; comp2 = scan2 + testDigit; comp3 = scan3 + testDigit;
						if (n[comp1] != n[comp2] || n[comp1] != n[comp3]) {
							isCandidate = false;
							break;
						}
						pattern[testDigit] = n[comp1];
					}
					if (isCandidate) {
						return pattern;
					}
				}
			}
		}
		return new int[]{};
	}
	
	public static String recip (final int n, int maxDigits) {
		String ret = new String();
		int num = 1; int rem; int div; int sum;
		int count =0 ;
		do{
			while (num < n){
				num *= 10;
			}
			div = num / n;
			rem = num - (div * n);
			num = rem;
			ret += div;
			count++;
		} while (count < maxDigits && rem != 0);
		return ret;
	}
}
